<script setup lang="ts">
import { computed, ref } from "vue";
import { computedRefreshableAsync } from "@/framework/vue/composable/computed-refreshable.ts";
import { withDefaultOnErrorAsync } from "@/framework/util/defaults.ts";
import { generateKeyPair } from "./util.ts";
import ToolView from "@/modules/tools/layout/tool-view.vue";
import { noop } from "@/framework/util/warning.ts";
import path from "@/framework/util/path.ts";
import { message } from "ant-design-vue";

const bits = ref(2048);
const bitsValid = computed(() => bits.value >= 256 && bits.value <= 16384 && bits.value % 8 === 0);
const emptyCerts = { publicKeyPem: "", privateKeyPem: "" };

const [certs, refreshCerts] = computedRefreshableAsync(
  () => withDefaultOnErrorAsync(() => generateKeyPair({ bits: bits.value }), emptyCerts),
  emptyCerts,
);

const saveFile = () => {
  if (certs.value?.publicKeyPem && certs.value?.privateKeyPem) {
    native.dialog
      .showOpenDirectoryDialog({ title: "选择保存目录" })
      .then(ret => {
        if (!ret.canceled) {
          native.fs.writeFile(path.join(ret.filePaths[0], "public.pem"), certs.value!.publicKeyPem);
          native.fs.writeFile(path.join(ret.filePaths[0], "private.pem"), certs.value!.privateKeyPem);
          message.success("保存成功");
        }
      })
      .catch(noop);
  }
};
</script>

<template>
  <tool-view title="RSA密钥对生成器" description="生成新的随机RSA私钥和公钥pem证书">
    <div class="pv-20 full-view flex-center">
      <a-form class="w-80p" :label-col="{ span: 5 }">
        <a-form-item label="Bits" help="应是 256 <= bits <= 16384，并且是 8 的倍数">
          <div class="flex col-gap-10">
            <a-input-number v-model:value="bits" :status="!bitsValid ? 'error' : undefined" :min="256" :max="16384" :step="8" class="flex-1" />
            <a-button @click="refreshCerts">重新生成</a-button>
            <a-button @click="saveFile">保存文件</a-button>
          </div>
        </a-form-item>
        <a-form-item label="公钥">
          <a-textarea :value="certs?.publicKeyPem" :auto-size="{ minRows: 10, maxRows: 10 }" />
        </a-form-item>
        <a-form-item label="私钥">
          <a-textarea :value="certs?.privateKeyPem" :auto-size="{ minRows: 15, maxRows: 15 }" />
        </a-form-item>
      </a-form>
    </div>
  </tool-view>
</template>

<style scoped lang="less"></style>
